package com.flca.frw.zk.util;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.ListModelArray;

import com.flca.frw.beanutils.MethodHelper;

public class ListModelHelper {

	private static ILabelProvider sLabelProvider;
	
	private static Logger logger = LoggerFactory.getLogger(ListModelHelper.class);
	
	public static void setup(ILabelProvider aLabelProvider) 
	{
		System.out.println("Setup ListModelHelper with " + aLabelProvider);
		sLabelProvider = aLabelProvider;
	}

	@SuppressWarnings("unchecked")
	public static void setSelectedItem(Combobox aComboBox, Object aValue) 
	{
		if (aValue != null) {
			String value = aValue.toString();
			List<Comboitem> items = aComboBox.getItems();
			for (Comboitem item : items) {
				if (item != null && item.getValue() != null) {
					if (item.getValue() instanceof Enum) {
						String enumValue = ((Enum) item.getValue()).name();
						if (value.equals(enumValue)) {
							aComboBox.setSelectedItem(item);
							return;
						}
					} else if (value.equals(item.getValue())) {
						aComboBox.setSelectedItem(item);
						return;
					} else if (aValue.equals(item.getValue())) {
						aComboBox.setSelectedItem(item);
						return;
					}
				}
			}
		} 
		if (aComboBox.getItems().size() > 0) {
			aComboBox.setSelectedIndex(0);
		}
	}
	
	public static ListModel makeListModel(Class<?> aEnum, boolean aPrompt) 
	{
		List<ListItem> list = new ArrayList<ListItem>();
		
		if (aPrompt) {
			list.add(new ListItem(null, "Kies ...."));
		}
		
		try {
			Method m = getEnumArrayMethod(aEnum);
			
			if (m != null) {
				
				Object arr = m.invoke(null, new Object[] {});
				if (arr != null && arr instanceof Object[]) {
					for (Object enumItem : (Object[]) arr) {
						String descr = "";
						if (sLabelProvider != null) {
							descr = sLabelProvider.getLabel(enumItem);
						}
						
						if (descr == null || descr.length() == 0) {
							logger.warn("no label descr found for " + enumItem.toString());
							descr = enumItem.toString();
						}
						
						list.add(new ListItem(enumItem, descr));
					}
				}
			}
		} catch (Exception e) {
			logger.error("ComboboxHelper.makeListModel() no valid Enum : " + aEnum, e);
		} 

		ListModel result = new ListModelArray(list);
		return result;
	}

	private static Method getEnumArrayMethod(Class<?> aEnum)
	{
		Method result = null;
		
		String methodNames[] = new String[] {"values", "toArray"};
		
		for (int i=0; i < methodNames.length; i++) {
			try {
				result = aEnum.getMethod(methodNames[i]);
				break;
			} catch(Exception e) {
			}
		}
		
		return result;
	}
	
	public static ListModel makeListModel(List<String> aItems, boolean aPrompt) 
	{
		List<ListItem> list = new ArrayList<ListItem>();
		
		if (aPrompt) {
			list.add(new ListItem(null, "Kies ..."));
		}
		
		for (String s : aItems) {
			if (!"NULL".equals(s)) {
				list.add(new ListItem(s, s));
			}
		}

		ListModel result = new ListModelArray(list);
		return result;
	}

	public static ListModel makeListModel(Object aObject, String aPropertyname)
	{
		return makeListModel(aObject, aPropertyname, false);
	}
	
	public static ListModel makeListModel(Object aObject, String aPropertyname, boolean aPrompt)
	{
		ListModel result = null;
		
		if (aObject != null && aPropertyname != null) {
			Method getter = MethodHelper.getGetter(aObject, aPropertyname);
			if (getter != null) {
				Class<?> rettyp = getter.getReturnType();
				result = makeListModel(rettyp, aPrompt);
			} else {
				logger.warn("no getter for : " + aPropertyname + " in " + aObject.getClass().getSimpleName());
			}
		}
		
		return result;
	}
	
}
